//
//  TYJsonData.m
//  Project
//
//  Created by 谢航宇_WORK on 2022/1/12.
//  Copyright © 2022 谢航宇. All rights reserved.
//

#import "TYJsonData.h"
#import <objc/runtime.h>

@implementation NSString (TYJsonData)
+ (NSString *)getStringFromObj:(id)obj {
    if (!obj) {
        return @"";
    }
    if ([obj isKindOfClass:[NSDictionary class]]) {
        return [NSString getStringFromDictionary:obj];
    }
    if ([obj isKindOfClass:[NSArray class]]) {
        return [NSString getStringFromArray:obj];
    }
    if ([obj isKindOfClass:[NSString class]]) {
        return obj;
    }
    return [NSString stringWithFormat:@"%@",obj];
}
+ (NSString *)getRequestStringFromDictionary:(NSDictionary *)dic{
    if ([dic isKindOfClass:[NSDictionary class]]) {
        //哈希排序
        NSStringCompareOptions comparisonOptions = NSLiteralSearch|NSNumericSearch|NSWidthInsensitiveSearch|NSForcedOrderingSearch;
        NSComparator sort = ^(NSString *obj1,NSString *obj2){
            NSRange range = NSMakeRange(0,obj1.length);
            return [obj1 compare:obj2 options:comparisonOptions range:range];
        };
        
        NSArray *resultArray = [dic.allKeys sortedArrayUsingComparator:sort];
        NSMutableString *string = [[NSMutableString alloc]init];
        for (NSString *key in resultArray) {
            if ([dic[key]isKindOfClass:[NSString class]]) {
                if (dic[key] !=nil && dic[key]) {
                    [string appendString:[NSString stringWithFormat:@"&%@=%@",key,dic[key]]];
                }
            }else if ([dic[key]isKindOfClass:[NSNumber class]]){
                if (dic[key] !=nil) {
                    [string appendString:[NSString stringWithFormat:@"&%@=%@",key,dic[key]]];
                }
            }else if ([dic[key]isKindOfClass:[NSArray class]]){
                [string appendString:[NSString stringWithFormat:@"&%@=%@",key,[NSString getStringFromArray:dic[key]]]];
            }else if ([dic[key]isKindOfClass:[NSDictionary class]]){
                [string appendString:[NSString stringWithFormat:@"&%@=%@",key,[NSString getStringFromDictionary:dic[key]]]];
            }
        }
        if (string.length>0) {
            [string deleteCharactersInRange:NSMakeRange(0, 1)];
        }
        return [[NSString stringWithFormat:@"%@",string] stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
    }
    return @"";
}

+ (NSString *)getStringFromDictionary:(NSDictionary *)dic{
    if ([dic isKindOfClass:[NSDictionary class]]) {
        //哈希排序
        NSStringCompareOptions comparisonOptions = NSLiteralSearch|NSNumericSearch|NSWidthInsensitiveSearch|NSForcedOrderingSearch;
        NSComparator sort = ^(NSString *obj1,NSString *obj2){
            NSRange range = NSMakeRange(0,obj1.length);
            return [obj1 compare:obj2 options:comparisonOptions range:range];
        };
        
        NSArray *resultArray = [dic.allKeys sortedArrayUsingComparator:sort];
        NSMutableString *string = [[NSMutableString alloc]init];
        for (NSString *key in resultArray) {
            if ([dic[key]isKindOfClass:[NSString class]]) {
                if (dic[key] !=nil && dic[key]) {
                    [string appendString:[NSString stringWithFormat:@",\"%@\":\"%@\"",key,dic[key]]];
                }
            }else if ([dic[key]isKindOfClass:[NSNumber class]]){
                if (dic[key] !=nil) {
                    [string appendString:[NSString stringWithFormat:@",\"%@\":%@",key,dic[key]]];
                }
            }else if ([dic[key]isKindOfClass:[NSArray class]]){
                [string appendString:[NSString stringWithFormat:@",\"%@\":%@",key,[NSString getStringFromArray:dic[key]]]];
            }else if ([dic[key]isKindOfClass:[NSDictionary class]]){
                [string appendString:[NSString stringWithFormat:@",\"%@\":%@",key,[NSString getStringFromDictionary:dic[key]]]];
            }
        }
        if (string.length>0) {
            [string deleteCharactersInRange:NSMakeRange(0, 1)];
        }
        return [NSString stringWithFormat:@"{%@}",[string stringByReplacingOccurrencesOfString:@"\n" withString:@"\\n"]];
    }
    return @"{}";
}

+ (NSString *)getEncodeStringFromDictionary:(NSDictionary *)dic{
    if ([dic isKindOfClass:[NSDictionary class]]) {
        //哈希排序
        NSStringCompareOptions comparisonOptions = NSLiteralSearch|NSNumericSearch|NSWidthInsensitiveSearch|NSForcedOrderingSearch;
        NSComparator sort = ^(NSString *obj1,NSString *obj2){
            NSRange range = NSMakeRange(0,obj1.length);
            return [obj1 compare:obj2 options:comparisonOptions range:range];
        };
        
        NSArray *resultArray = [dic.allKeys sortedArrayUsingComparator:sort];
        NSMutableString *string = [[NSMutableString alloc]init];
        for (NSString *key in resultArray) {
            if ([dic[key]isKindOfClass:[NSString class]]) {
                if (dic[key] !=nil && dic[key]) {
                    [string appendString:[NSString stringWithFormat:@",\"%@\":\"%@\"",key,[self encodeValue:dic[key]]]];
                }
            }else if ([dic[key]isKindOfClass:[NSNumber class]]){
                if (dic[key] !=nil) {
                    [string appendString:[NSString stringWithFormat:@",\"%@\":%@",key,dic[key]]];
                }
            }else if ([dic[key]isKindOfClass:[NSArray class]]){
                [string appendString:[NSString stringWithFormat:@",\"%@\":%@",key,[NSString getEncodeStringFromArray:dic[key]]]];
            }else if ([dic[key]isKindOfClass:[NSDictionary class]]){
                [string appendString:[NSString stringWithFormat:@",\"%@\":%@",key,[NSString getEncodeStringFromDictionary:dic[key]]]];
            }
        }
        if (string.length>0) {
            [string deleteCharactersInRange:NSMakeRange(0, 1)];
        }
        return [NSString stringWithFormat:@"{%@}",[string stringByReplacingOccurrencesOfString:@"\n" withString:@"\\n"]];
    }
    return @"{}";
}

+ (NSString*)encodeValue:(NSString*)value {
    NSString* encodedValue = value;
    if (value.length > 0) {
        NSCharacterSet *charset = [[NSCharacterSet characterSetWithCharactersInString:@"!*'();:@&=+$,/?%#[]"]invertedSet];
        encodedValue = [value stringByAddingPercentEncodingWithAllowedCharacters:charset];
    }
    return encodedValue;
}

+ (NSString *)getStringFromArray:(NSArray *)ary{
    if ([ary isKindOfClass:[NSArray class]]) {
        NSMutableString *string = [[NSMutableString alloc]init];
        for (id obj in ary) {
            if ([obj isKindOfClass:[NSString class]]) {
                if (obj !=nil) {
                    [string appendString:[NSString stringWithFormat:@",\"%@\"",obj]];
                }
            }else if ([obj isKindOfClass:[NSNumber class]]){
                if (obj !=nil) {
                    [string appendString:[NSString stringWithFormat:@",%@",obj]];
                }
            }else if ([obj isKindOfClass:[NSArray class]]){
                [string appendString:[NSString stringWithFormat:@",%@",[NSString getStringFromArray:(NSArray *)obj]]];
            }else if ([obj isKindOfClass:[NSDictionary class]]){
                [string appendString:[NSString stringWithFormat:@",%@",[NSString getStringFromDictionary:(NSDictionary *)obj]]];
            }
        }
        if (string.length>0) {
            [string deleteCharactersInRange:NSMakeRange(0, 1)];
        }
        return [NSString stringWithFormat:@"[%@]",string];
    }
    return @"[]";
}

+ (NSString *)getEncodeStringFromArray:(NSArray *)ary{
    if ([ary isKindOfClass:[NSArray class]]) {
        NSMutableString *string = [[NSMutableString alloc]init];
        for (id obj in ary) {
            if ([obj isKindOfClass:[NSString class]]) {
                if (obj !=nil) {
                    [string appendString:[NSString stringWithFormat:@",\"%@\"",[self encodeValue:obj]]];
                }
            }else if ([obj isKindOfClass:[NSNumber class]]){
                if (obj !=nil) {
                    [string appendString:[NSString stringWithFormat:@",%@",obj]];
                }
            }else if ([obj isKindOfClass:[NSArray class]]){
                [string appendString:[NSString stringWithFormat:@",%@",[NSString getEncodeStringFromArray:(NSArray *)obj]]];
            }else if ([obj isKindOfClass:[NSDictionary class]]){
                [string appendString:[NSString stringWithFormat:@",%@",[NSString getEncodeStringFromDictionary:(NSDictionary *)obj]]];
            }
        }
        if (string.length>0) {
            [string deleteCharactersInRange:NSMakeRange(0, 1)];
        }
        return [NSString stringWithFormat:@"[%@]",string];
    }
    return @"[]";
}
@end


@implementation NSDictionary (TYJsonData)
+ (NSDictionary *)getDictionaryFromObj:(id)obj {
    if (!obj) {
        return @{};
    }
    if ([obj isKindOfClass:[NSDictionary class]]) {
        return [NSDictionary getPropertiesFromDic:obj];
    }
    if ([obj isKindOfClass:[NSArray class]]) {
        return @{};
    }
    if ([obj isKindOfClass:[NSString class]]) {
        return [NSDictionary getPropertiesFromDic:obj];
    }
    if ([obj isKindOfClass:[NSData class]]) {
        return [NSDictionary getDictionaryFromData:obj];
    }
    return @{};
}

+ (NSDictionary *)getDictionaryFromString:(NSString *)jsonString {
    if (jsonString == nil) {
        return @{};
    }
    if ([jsonString isKindOfClass:[NSDictionary class]]) {
        return (NSDictionary *)jsonString;
    }
    if ([jsonString isKindOfClass:[NSData class]]) {
        return [NSDictionary getDictionaryFromData:(NSData *)jsonString];
    }
    if (![jsonString isKindOfClass:[NSString class]]) {
        return @{};
    }
    jsonString = [NSString stringWithFormat:@"%@",jsonString];
    NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding]; 
    return [NSDictionary getDictionaryFromData:jsonData];
}

+ (NSDictionary *)getDictionaryFromData:(NSData *)data {
    if (data == nil) {
        return @{};
    }
    if ([data isKindOfClass:[NSDictionary class]]) {
        return (NSDictionary *)data;
    }
    if ([data isKindOfClass:[NSString class]]) {
        return [NSDictionary getDictionaryFromString:(NSString *)data];
    }
    if (![data isKindOfClass:[NSData class]]) {
        return @{};
    }
    NSError *err;
    NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&err];
    if(err) {
        NSLog(@"json解析失败：%@",err);
        return @{};
    }
    return dic;
}

+ (NSDictionary *)getAllPropertiesKeyAndValue:(id)obj {
     NSMutableDictionary * attributeDic = [[NSMutableDictionary alloc]init];
     unsigned int count;
     objc_property_t *properties = class_copyPropertyList([obj class], &count);
     for(int i = 0; i < count; i++){
          objc_property_t property = properties[i];
          NSString * key = [NSString stringWithUTF8String:property_getName(property)];
          NSString * type = [NSString stringWithUTF8String:property_getAttributes(property)];
          if ([type containsString:@"T@\""] && [type containsString:@"\","]) {
               NSRange range1 =  [type rangeOfString:@"T@\""];
               NSRange range2 =  [type rangeOfString:@"\","];
               NSString * types = [type substringWithRange:NSMakeRange(range1.length, range2.location - range1.length)];
              types = [types stringByReplacingOccurrencesOfString:@"<Optional>" withString:@""];
               if ([types isEqualToString:@"NSString"]) {
                    [attributeDic setObject:[obj valueForKey:key]?[obj valueForKey:key]:@"" forKey:key];
               }else if ([types isEqualToString:@"NSNumber"]) {
                    [attributeDic setObject:[obj valueForKey:key]?[obj valueForKey:key]:@(-99) forKey:key];
               }else if ([types isEqualToString:@"NSArray"]) {
                    [attributeDic setObject:[obj valueForKey:key]?[NSDictionary getPropertiesFromAry:[obj valueForKey:key]]:[[NSArray alloc]init] forKey:key];
               }else if ([types isEqualToString:@"NSMutableArray"]) {
                    [attributeDic setObject:[obj valueForKey:key]?[NSDictionary getPropertiesFromAry:[obj valueForKey:key]]:[[NSMutableArray alloc]init] forKey:key];
               }else if ([types isEqualToString:@"NSDictionary"]) {
                    [attributeDic setObject:[obj valueForKey:key]?[NSDictionary getPropertiesFromDic:[obj valueForKey:key]]:[[NSDictionary alloc]init] forKey:key];
               }else if ([types isEqualToString:@"NSMutableDictionary"]) {
                    [attributeDic setObject:[obj valueForKey:key]?[NSDictionary getPropertiesFromDic:[obj valueForKey:key]]:[[NSMutableDictionary alloc]init] forKey:key];
               }else if ([obj valueForKey:key] && ![[obj valueForKey:key]isKindOfClass:[NSNull class]]) {
                    [attributeDic setObject:[NSDictionary getAllPropertiesKeyAndValue:[obj valueForKey:key]] forKey:key];
               }
               
          }
          
     }
     free(properties);
     return attributeDic;
}

+ (NSDictionary *)getPropertiesFromDic:(NSDictionary *)dic {
    NSMutableDictionary * muDic = [[NSMutableDictionary alloc]init];
    if (![dic isKindOfClass:[NSDictionary class]]) {
        return muDic;
    }
    for (NSString * key in dic.allKeys) {
        id obj = dic[key];
        if ([obj isKindOfClass:[NSString class]] || [obj isKindOfClass:[NSNumber class]]) {
            [muDic setObject:obj forKey:key];
        }else if ([obj isKindOfClass:[NSArray class]]) {
            [muDic setObject:[NSDictionary getPropertiesFromAry:obj] forKey:key];
        }else if ([obj isKindOfClass:[NSDictionary class]]) {
            [muDic setObject:[NSDictionary getPropertiesFromDic:obj] forKey:key];
        }else {
            [muDic setObject:[NSDictionary getAllPropertiesKeyAndValue:obj] forKey:key];
        }
    }
    return muDic;
}

+ (NSArray *)getPropertiesFromAry:(NSArray *)ary {
    NSMutableArray * muAry = [[NSMutableArray alloc]init];
    if (![ary isKindOfClass:[NSArray class]]) {
        return muAry;
    }
    for (id obj in ary) {
        if ([obj isKindOfClass:[NSString class]] || [obj isKindOfClass:[NSNumber class]]) {
            [muAry addObject:obj];
        }else if ([obj isKindOfClass:[NSArray class]]) {
            [muAry addObject:[NSDictionary getPropertiesFromAry:obj]];
        }else if ([obj isKindOfClass:[NSDictionary class]]) {
            [muAry addObject:[NSDictionary getPropertiesFromDic:obj]];
        }else {
            [muAry addObject:[NSDictionary getAllPropertiesKeyAndValue:obj]];
        }
    }
    return muAry;
}

@end
